<div class="tmd-doc">
<h1 class="tmd-header-1">
Pointers in Go
</h1>
<p></p>
<div class="tmd-usual">
Although Go absorbs many features from all kinds of other languages, Go is mainly viewed as a C family language. One evidence is Go also supports pointers. Go pointers and C pointers are much similar in many aspects, but there are also some differences between Go pointers and C pointers. This article will list all kinds of concepts and details related to pointers in Go.
</div>
<p></p>
<h3 class="tmd-header-3">
Memory Addresses
</h3>
<p></p>
<div class="tmd-usual">
A memory address means a specific memory location in programming.
</div>
<p></p>
<div class="tmd-usual">
Generally, a memory address is stored as an unsigned native (integer) word. The size of a native word is 4 (bytes) on 32-bit architectures and 8 (bytes) on 64-bit architectures. So the theoretical maximum memory space size is 2<sup>32</sup> bytes, a.k.a. 4GB (1GB == 2<sup>30</sup> bytes), on 32-bit architectures, and is 2<sup>64</sup> bytes a.k.a 16EB (1EB == 1024PB, 1PB == 1024TB, 1TB == 1024GB), on 64-bit architectures.
</div>
<p></p>
<div class="tmd-usual">
Memory addresses are often represented with hex integer literals, such as <code class="tmd-code-span">0x1234CDEF</code>.
</div>
<p></p>
<h3 class="tmd-header-3">
Value Addresses
</h3>
<p></p>
<div class="tmd-usual">
The address of a value means the start address of the memory segment occupied by the <a href="value-part.html">direct part</a> of the value.
</div>
<p></p>
<p></p>
<h3 class="tmd-header-3">
What Are Pointers?
</h3>
<p></p>
<div class="tmd-usual">
Pointer is one kind of type in Go. A pointer value is used to store a memory address, which is generally the address of another value.
</div>
<p></p>
<div class="tmd-usual">
Unlike C language, for safety reason, there are some restrictions made for Go pointers. Please read the following sections for details.
</div>
<p></p>
<h3 class="tmd-header-3">
Go Pointer Types and Values
</h3>
<p></p>
<div class="tmd-usual">
In Go, an unnamed pointer type can be represented with <code class="tmd-code-span">*T</code>, where <code class="tmd-code-span">T</code> can be an arbitrary type. Type <code class="tmd-code-span">T</code> is called the base type of pointer type <code class="tmd-code-span">*T</code>.
</div>
<p></p>
<div class="tmd-usual">
We can declare named pointer types, but generally, it’s not recommended to use named pointer types, for unnamed pointer types have better readabilities.
</div>
<p></p>
<div class="tmd-usual">
If the <a href="type-system-overview.html#underlying-type">underlying type</a> of a named pointer type is <code class="tmd-code-span">*T</code>, then the base type of the named pointer type is <code class="tmd-code-span">T</code>.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
Two unnamed pointer types with the same base type are the same type.
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">*int  // An unnamed pointer type whose base type is int.
**int // An unnamed pointer type whose base type is *int.

// Ptr is a named pointer type whose base type is int.
type Ptr *int
// PP is a named pointer type whose base type is Ptr.
type PP *Ptr
</code></pre>
<p></p>
<div class="tmd-usual">
Zero values of any pointer types are represented with the predeclared <code class="tmd-code-span">nil</code>. No addresses are stored in nil pointer values.
</div>
<p></p>
<div class="tmd-usual">
A value of a pointer type whose base type is <code class="tmd-code-span">T</code> can only store the addresses of values of type <code class="tmd-code-span">T</code>.
</div>
<p></p>
<h3 id="references" class="tmd-header-3">
About the Word "Reference"
</h3>
<p></p>
<div class="tmd-usual">
In Go 101, the word "reference" indicates a relation. For example, if a pointer value stores the address of another value, then we can say the pointer value (directly) references the other value, and the other value has at least one reference. The uses of the word "reference" in Go 101 are consistent with Go specification.
</div>
<p></p>
<div class="tmd-usual">
When a pointer value references another value, we also often say the pointer value points to the other value.
</div>
<p></p>
<h3 class="tmd-header-3">
How to Get a Pointer Value and What Are Addressable Values?
</h3>
<p></p>
<div class="tmd-usual">
There are two ways to get a non-nil pointer value.
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
The built-in <code class="tmd-code-span">new</code> function can be used to allocate memory for a value of any type. <code class="tmd-code-span">new(T)</code> will allocate memory for a <code class="tmd-code-span">T</code> value (an anonymous variable) and return the address of the <code class="tmd-code-span">T</code> value. The allocated value is a zero value of type <code class="tmd-code-span">T</code>. The returned address is viewed as a pointer value of type <code class="tmd-code-span">*T</code>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
We can also take the addresses of values which are addressable in Go. For an addressable value <code class="tmd-code-span">t</code> of type <code class="tmd-code-span">T</code>, we can use the expression <code class="tmd-code-span">&amp;t</code> to take the address of <code class="tmd-code-span">t</code>, where <code class="tmd-code-span">&amp;</code> is the operator to take value addresses. The type of <code class="tmd-code-span">&amp;t</code> is viewed as <code class="tmd-code-span">*T</code>.
</div>
</li>
</ol>
<p></p>
<div class="tmd-usual">
Generally speaking, an addressable value means a value which is hosted at somewhere in memory. Currently, we just need to know that all variables are addressable, whereas constants, function calls and explicit conversion results are all unaddressable. When a variable is declared, Go runtime will allocate a piece of memory for the variable. The starting address of that piece of memory is the address of the variable.
</div>
<p></p>
<div class="tmd-usual">
We will learn other addressable and unaddressable values from other articles later. If you have already been familiar with Go, you can read <a href="summaries.html#not-addressable">this summary</a> to get the lists of addressable and unaddressable values in Go.
</div>
<p></p>
<p></p>
<div class="tmd-usual">
The next section will show an example on how to get pointer values.
</div>
<p></p>
<h3 class="tmd-header-3">
Pointer Dereference
</h3>
<p></p>
<div class="tmd-usual">
Given a pointer value <code class="tmd-code-span">p</code> of a pointer type whose base type is <code class="tmd-code-span">T</code>, how can you get the value at the address stored in the pointer (a.k.a., the value being referenced by the pointer)? Just use the expression <code class="tmd-code-span">*p</code>, where <code class="tmd-code-span">*</code> is called dereference operator. <code class="tmd-code-span">*p</code> is called the dereference of pointer <code class="tmd-code-span">p</code>. Pointer dereference is the inverse process of address taking. The result of <code class="tmd-code-span">*p</code> is a value of type <code class="tmd-code-span">T</code> (the base type of the type of <code class="tmd-code-span">p</code>).
</div>
<p></p>
<div class="tmd-usual">
Dereferencing a nil pointer causes a runtime panic.
</div>
<p></p>
<div class="tmd-usual">
The following program shows some address taking and pointer dereference examples:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func main() {
	p0 := new(int)   // p0 points to a zero int value.
	fmt.Println(p0)  // (a hex address string)
	fmt.Println(*p0) // 0

	// x is a copy of the value at
	// the address stored in p0.
	x := *p0
	// Both take the address of x.
	// x, *p1 and *p2 represent the same value.
	p1, p2 := &amp;x, &amp;x
	fmt.Println(p1 == p2) // true
	fmt.Println(p0 == p1) // false
	p3 := &amp;*p0 // &lt;=&gt; p3 := &amp;(*p0) &lt;=&gt; p3 := p0
	// Now, p3 and p0 store the same address.
	fmt.Println(p0 == p3) // true
	*p0, *p1 = 123, 789
	fmt.Println(*p2, x, *p3) // 789 789 123

	fmt.Printf("%T, %T \n", *p0, x) // int, int
	fmt.Printf("%T, %T \n", p0, p1) // *int, *int
}
</code></pre>
<p></p>
<div class="tmd-usual">
The following picture depicts the relations of the values used in the above program.
</div>
<p></p>
<div class="tmd-base tmd-align-center">
<div class="tmd-usual">
<img src="res/pointer.png" class="tmd-media"/>
</div>
</div>
<p></p>
<h3 class="tmd-header-3">
Why Do We Need Pointers?
</h3>
<p></p>
<div class="tmd-usual">
Let's view an example firstly.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func double(x int) {
	x += x
}

func main() {
	var a = 3
	double(a)
	fmt.Println(a) // 3
}
</code></pre>
<p></p>
<div class="tmd-usual">
The <code class="tmd-code-span">double</code> function in the above example is expected to modify the input argument by doubling it. However, it fails. Why? Because all value assignments, including function argument passing, are value copying in Go. What the <code class="tmd-code-span">double</code> function modified is a copy (<code class="tmd-code-span">x</code>) of variable <code class="tmd-code-span">a</code> but not variable <code class="tmd-code-span">a</code>.
</div>
<p></p>
<div class="tmd-usual">
One solution to fix the above <code class="tmd-code-span">double</code> function is let it return the modification result. This solution doesn't always work for all scenarios. The following example shows another solution, by using a pointer parameter.
</div>
<p></p>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func double(x *int) {
	*x += *x
	x = nil // the line is just for explanation purpose
}

func main() {
	var a = 3
	double(&amp;a)
	fmt.Println(a) // 6
	p := &amp;a
	double(p)
	fmt.Println(a, p == nil) // 12 false
}
</code></pre>
<p></p>
<div class="tmd-usual">
We can find that, by changing the parameter to a pointer type, the passed pointer argument <code class="tmd-code-span">&amp;a</code> and its copy <code class="tmd-code-span">x</code> used in the function body both reference the same value, so the modification on <code class="tmd-code-span">*x</code> is equivalent to a modification on <code class="tmd-code-span">*p</code>, a.k.a., variable <code class="tmd-code-span">a</code>. In other words, the modification in the <code class="tmd-code-span">double</code> function body can be reflected out of the function now.
</div>
<p></p>
<div class="tmd-usual">
Surely, the modification of the copy of the passed pointer argument itself still can't be reflected on the passed pointer argument. After the second <code class="tmd-code-span">double</code> function call, the local pointer <code class="tmd-code-span">p</code> doesn't get modified to <code class="tmd-code-span">nil</code>.
</div>
<p></p>
<div class="tmd-usual">
In short, pointers provide indirect ways to access some values. Many languages do not have the concept of pointers. However, pointers are just hidden under other concepts in those languages.
</div>
<p></p>
<h3 class="tmd-header-3">
Return Pointers of Local Variables Is Safe in Go
</h3>
<p></p>
<div class="tmd-usual">
Unlike C language, Go is a language supporting garbage collection, so return the address of a local variable is absolutely safe in Go.
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">func newInt() *int {
	a := 3
	return &amp;a
}
</code></pre>
<p></p>
<h3 id="restrictions" class="tmd-header-3">
Restrictions on Pointers in Go
</h3>
<p></p>
<div class="tmd-usual">
For safety reasons, Go makes some restrictions to pointers (comparing to pointers in C language). By applying these restrictions, Go keeps the benefits of pointers, and avoids the dangerousness of pointers at the same time.
</div>
<p></p>
<h4 class="tmd-header-4">
Go pointer values don't support arithmetic operations
</h4>
<p></p>
<div class="tmd-usual">
In Go, pointers can't do arithmetic operations. For a pointer <code class="tmd-code-span">p</code>, <code class="tmd-code-span">p++</code> and <code class="tmd-code-span">p-2</code> are both illegal.
</div>
<p></p>
<div class="tmd-usual">
If <code class="tmd-code-span">p</code> is a pointer to a numeric value, compilers will view <code class="tmd-code-span">*p++</code> is a legal statement and treat it as <code class="tmd-code-span">(*p)++</code>. In other words, the precedence of the pointer dereference operator <code class="tmd-code-span">*</code> is higher than the increment operator <code class="tmd-code-span">++</code> and decrement operator <code class="tmd-code-span">--</code>.
</div>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

import "fmt"

func main() {
	a := int64(5)
	p := &amp;a

	// The following two lines don't compile.
	/*
	p++
	p = (&amp;a) + 8
	*/

	*p++
	fmt.Println(*p, a)   // 6 6
	fmt.Println(p == &amp;a) // true

	*&amp;a++
	*&amp;*&amp;a++
	**&amp;p++
	*&amp;*p++
	fmt.Println(*p, a) // 10 10
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
A pointer value can't be converted to an arbitrary pointer type
</h4>
<p></p>
<div class="tmd-usual">
In Go, a pointer value of pointer type <code class="tmd-code-span">T1</code> can be directly and explicitly converted to another pointer type <code class="tmd-code-span">T2</code> only if either of the following two conditions is get satisfied.
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
The underlying types of type <code class="tmd-code-span">T1</code> and <code class="tmd-code-span">T2</code> are identical (ignoring struct tags), in particular if either <code class="tmd-code-span">T1</code> and <code class="tmd-code-span">T2</code> is a 	<a href="type-system-overview.html#named-type">unnamed</a> type and their underlying types are identical (considering struct tags), then the conversion can be implicit. Struct types and values will be explained in <a href="struct.html">the next article</a>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
Type <code class="tmd-code-span">T1</code> and <code class="tmd-code-span">T2</code> are both unnamed pointer types and the underlying types of their base types are identical (ignoring struct tags).
</div>
</li>
</ol>
<p></p>
<p></p>
<div class="tmd-usual">
For example, for the below shown pointer types:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">type MyInt int64
type Ta    *int64
type Tb    *MyInt
</code></pre>
<p></p>
<div class="tmd-usual">
the following facts exist:
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
values of type <code class="tmd-code-span">*int64</code> can be implicitly converted to type <code class="tmd-code-span">Ta</code>, and vice versa, for their underlying types are both <code class="tmd-code-span">*int64</code>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
values of type <code class="tmd-code-span">*MyInt</code> can be implicitly converted to type <code class="tmd-code-span">Tb</code>, and vice versa, for their underlying types are both <code class="tmd-code-span">*MyInt</code>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
values of type <code class="tmd-code-span">*MyInt</code> can be explicitly converted to type <code class="tmd-code-span">*int64</code>, and vice versa, for they are both unnamed and the underlying types of their base types are both <code class="tmd-code-span">int64</code>.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
values of type <code class="tmd-code-span">Ta</code> can't be directly converted to type <code class="tmd-code-span">Tb</code>, even if explicitly. However, by the just listed first three facts, a value <code class="tmd-code-span">pa</code> of type <code class="tmd-code-span">Ta</code> can be indirectly converted to type <code class="tmd-code-span">Tb</code> by nesting three explicit conversions, <code class="tmd-code-span">Tb((*MyInt)((*int64)(pa)))</code>.
</div>
</li>
</ol>
<p></p>
<div class="tmd-usual">
None of these pointer types can be converted to type <code class="tmd-code-span">*uint64</code>, in any safe ways.
</div>
<p></p>
<h4 class="tmd-header-4">
A pointer value can't be compared with values of an arbitrary pointer type
</h4>
<p></p>
<div class="tmd-usual">
In Go, pointers can be compared with <code class="tmd-code-span">==</code> and <code class="tmd-code-span">!=</code> operators. Two Go pointer values can only be compared if either of the following three conditions are satisfied.
</div>
<ol class="tmd-list">
<li class="tmd-list-item">
<div class="tmd-usual">
The types of the two Go pointers are identical.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
One pointer value can be implicitly converted to the pointer type of the other. In other words, the underlying types of the two types must be identical and either of the two types of the two Go pointers is an unnamed type.
</div>
</li>
<li class="tmd-list-item">
<div class="tmd-usual">
One and only one of the two pointers is represented with the bare (untyped) <code class="tmd-code-span">nil</code> identifier.
</div>
</li>
</ol>
<p></p>
<div class="tmd-usual">
Example:
</div>
<pre class="tmd-code line-numbers">
<code class="language-go">package main

func main() {
	type MyInt int64
	type Ta    *int64
	type Tb    *MyInt

	// 4 nil pointers of different types.
	var pa0 Ta
	var pa1 *int64
	var pb0 Tb
	var pb1 *MyInt

	// The following 6 lines all compile okay.
	// The comparison results are all true.
	_ = pa0 == pa1
	_ = pb0 == pb1
	_ = pa0 == nil
	_ = pa1 == nil
	_ = pb0 == nil
	_ = pb1 == nil

	// None of the following 3 lines compile ok.
	/*
	_ = pa0 == pb0
	_ = pa1 == pb1
	_ = pa0 == Tb(nil)
	*/
}
</code></pre>
<p></p>
<h4 class="tmd-header-4">
A pointer value can't be assigned to pointer values of other pointer types
</h4>
<p></p>
<div class="tmd-usual">
The conditions to assign a pointer value to another pointer value are the same as the conditions to compare a pointer value to another pointer value, which are listed above.
</div>
<p></p>
<h3 class="tmd-header-3">
It's Possible to Break the Go Pointer Restrictions
</h3>
<p></p>
<div class="tmd-usual">
As the start of this article has mentioned, the mechanisms (specifically, the <code class="tmd-code-span">unsafe.Pointer</code> type) provided by <a href="unsafe.html">the <code class="tmd-code-span">unsafe</code> standard package</a> can be used to break the restrictions made for pointers in Go. The <code class="tmd-code-span">unsafe.Pointer</code> type is like the <code class="tmd-code-span">void*</code> in C. In general the unsafe ways are not recommended to use.
</div>
<p></p>
<p></p>
</div>
